// 36. Valid Sudoku
// Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules.

// The Sudoku board could be partially filled, where empty cells are filled with the character '.'.

// Note:
// A valid Sudoku board (partially filled) is not necessarily solvable. Only the filled cells need to be validated.

package main

const (
	SIZE = 9
)

func isValidSudoku(board [][]byte) bool {
	if len(board) != SIZE {
		return false
	}

	vertical, horizontal, square := [SIZE][SIZE]int{}, [SIZE][SIZE]int{}, [SIZE][SIZE]int{}
	i, j, k, n := 0, 0, 0, 0
	var num byte

	for i = 0; i < SIZE; i++ {
		if len(board) != SIZE {
			return false
		}

		for j = 0; j < SIZE; j++ {
			num = board[i][j]
			if num == '.' {
				continue
			}
			if '9' < num || num < '1' {
				return false
			}

			n = int(num - '1')
			if vertical[i][n] > 0 {
				return false
			}
			vertical[i][n]++

			if horizontal[j][n] > 0 {
				return false
			}
			horizontal[j][n]++

			k = (i/3)*3 + j/3
			if square[k][n] > 0 {
				return false
			}
			square[k][n]++
		}
	}
	return true
}

func main() {
	board := [][]byte{
		[]byte{'5', '3', '.', '.', '7', '.', '.', '.', '.'},
		[]byte{'6', '.', '.', '1', '9', '5', '.', '.', '.'},
		[]byte{'.', '9', '8', '.', '.', '.', '.', '6', '.'},

		[]byte{'8', '.', '.', '.', '6', '.', '.', '.', '3'},
		[]byte{'4', '.', '.', '8', '.', '3', '.', '.', '1'},
		[]byte{'7', '.', '.', '.', '2', '.', '.', '.', '6'},

		[]byte{'.', '6', '.', '.', '.', '.', '2', '8', '.'},
		[]byte{'.', '.', '.', '4', '1', '9', '.', '.', '5'},
		[]byte{'.', '.', '.', '.', '8', '.', '.', '7', '9'},
	}
	println(isValidSudoku(board))
}
